package com.lframework.common.utils;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.lframework.common.constants.StringPool;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 时间工具类
 *
 * @author laich
 */
public class DateUtil extends cn.hutool.core.date.DateUtil {

  private static final SimpleDateFormat YYYY_MM_DD_HH_MM_SS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  private static final SimpleDateFormat YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd");

  /**
   * 时间戳转字符串  如果时间存MySQL需要/1000
   * @param timestamp 时间戳
   * @return 字符串
   */
  public static String toTimeStr(Long timestamp) {
    final Date date = new Date(timestamp);
    return YYYY_MM_DD_HH_MM_SS.format(date);
  }

  public static String tostr_Day(Long timestamp) {
    final Date date = new Date(timestamp);
    return YYYY_MM_DD.format(date);
  }

  /**
   * 时间戳返回周期数
   *
   * @param currentTimeMillis 时间戳
   * @return 字符串
   */
  public static Integer covertCycle(Long currentTimeMillis) {
    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    gregorianCalendar.setTimeInMillis(currentTimeMillis);
    Integer cycle = gregorianCalendar.get(Calendar.DAY_OF_WEEK) - 1;
    return cycle;
  }

  public static Long addMinApi(Long timestamp,Integer min) {
    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    gregorianCalendar.setTimeInMillis(timestamp);
    gregorianCalendar.add(GregorianCalendar.MINUTE,min);
    return gregorianCalendar.getTimeInMillis();
  }

  public static Long addHour(Long timestamp,Integer h) {
    GregorianCalendar gregorianCalendar = new GregorianCalendar();
    gregorianCalendar.setTimeInMillis(timestamp);
    gregorianCalendar.add(GregorianCalendar.HOUR,h);
    return gregorianCalendar.getTimeInMillis();
  }

  public static int getHour(Long timestamp) {
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTimeInMillis(timestamp);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    return hour;
  }

  public static int getMin(Long timestamp) {
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTimeInMillis(timestamp);
    int min = calendar.get(Calendar.MINUTE);
    return min;
  }

  public static String getYestoryDate() {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DATE,-1);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    return sdf.format(calendar.getTime());
  }

  public static Long toStampYYYY_MM_DD(String str) throws ParseException {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date = simpleDateFormat.parse(str);
    return date.getTime();
  }

  public static Long todayYYYY_MM_DD() throws ParseException {
    return DateUtil.toStampYYYY_MM_DD(DateUtil.tostr_Day(new Date().getTime()));
  }

  public static String formatDate(LocalDate localDate) {

    return LocalDateTimeUtil.formatNormal(localDate);
  }

  public static String formatDate(LocalDate localDate, String format) {

    return LocalDateTimeUtil.format(localDate, format);
  }

  public static LocalTime toLocalTime(Date date) {
    if (date == null) {
      return null;
    }
    return LocalDateTimeUtil.of(date).toLocalTime();
  }

  public static LocalDate toLocalDate(Date date) {
    if (date == null) {
      return null;
    }
    return LocalDateTimeUtil.of(date).toLocalDate();
  }

  public static Date toDate(LocalDateTime dateTime) {

    if (dateTime == null) {
      return null;
    }

    return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  public static Date toDate(LocalDate date) {

    if (date == null) {
      return null;
    }

    return Date.from(date.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
  }

  public static LocalDateTime toLocalDateTime(LocalDate localDate) {

    return LocalDateTime.of(localDate, LocalTime.MIN);
  }

  public static LocalDateTime toLocalDateTimeMax(LocalDate localDate) {

    return LocalDateTime.of(localDate, LocalTime.MAX.withNano(0));
  }

  public static String formatDateTime(LocalDateTime localDateTime) {

    return formatDateTime(localDateTime, StringPool.DATE_TIME_PATTERN);
  }

  public static String formatDateTime(LocalDateTime localDateTime, String pattern) {

    return format(localDateTime, pattern);
  }

  public static long getTime(LocalDateTime localDateTime) {

    return Timestamp.valueOf(localDateTime).getTime();
  }

  public static long getTime(LocalDate localDate) {

    return Timestamp.valueOf(toLocalDateTime(localDate)).getTime();
  }

  public static long getTime(Date date) {

    return date.getTime();
  }
}
